package com.gitee.cirnochat.user.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gitee.cirnochat.common.utils.RequestUtils;
import com.gitee.cirnochat.user.mapper.FriendMapper;
import com.gitee.cirnochat.user.model.entity.Friend;
import com.gitee.cirnochat.user.model.entity.FriendInfo;
import com.gitee.cirnochat.user.model.entity.User;
import com.gitee.cirnochat.user.model.enums.UserStatus;
import com.gitee.cirnochat.user.model.vo.resp.FriendDetailVo;
import com.gitee.cirnochat.user.model.vo.resp.FriendVo;
import com.gitee.cirnochat.user.service.FriendService;
import com.gitee.cirnochat.user.service.UserService;
import com.gitee.cirnochat.websocket.service.manager.SessionManager;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;

import static com.gitee.cirnochat.common.constant.RedisKey.USER_LAST_ONLINE_KEY;


/**
 * @author FlanChan
 * @description 针对表【friend(好友关系表)】的数据库操作Service实现
 * @createDate 2025-04-17 14:52:51
 */
@Service
@RequiredArgsConstructor
public class FriendServiceImpl extends ServiceImpl<FriendMapper, Friend>
        implements FriendService {

    private final UserService userService;
    private final SessionManager sessionManager;
    private final StringRedisTemplate redisTemplate;

    //region 查询

    @Override
    public List<FriendVo> listFriends(Long userId) {
        List<FriendVo> records = this.baseMapper.selectFriends(userId).stream().map(FriendVo::new).toList();
        records.forEach(e -> {
            e.setFriendStatus(sessionManager.isOnline(e.getId()) ? UserStatus.ONLINE : UserStatus.OFFLINE);
            String lastOnlineTimeStr = redisTemplate.opsForValue().get(USER_LAST_ONLINE_KEY + e.getId());
            e.setLastOnlineTime(lastOnlineTimeStr != null ? LocalDateTime.parse(lastOnlineTimeStr) : null);
        });
        return records.isEmpty() ? List.of() : records;
    }


    @Override
    public FriendDetailVo getFriendById(Long id, Long userId) {
        FriendInfo friendInfo = this.baseMapper.selectFriendById(id, userId);
        return new FriendDetailVo(friendInfo);
    }

    @Override
    public List<Friend> getFriends(Long userId) {
        return this.list(new LambdaQueryWrapper<>(Friend.class)
                .eq(Friend::getUserId, userId));
    }



    @Override
    public boolean isFriend(Long userId, Long friendId) {
        // 查询好友关系
        return this.exists(new LambdaQueryWrapper<>(Friend.class)
                .eq(Friend::getUserId, userId)
                .eq(Friend::getFriendId, friendId));
    }

    //endregion

    //region 更新

    @Override
    public void updateRemark(Long friendId, String remark, HttpServletRequest request) {
        // 查询当前用户 UUID
        Long userId = RequestUtils.getUserId(request);
        User friend = userService.getById(friendId);

        if (friend == null) {
            throw new RuntimeException("用户不存在");
        }
        if (this.getOne(new LambdaQueryWrapper<>(Friend.class)
                .eq(Friend::getUserId, userId)
                .eq(Friend::getFriendId, friend.getId())) == null) {
            throw new RuntimeException("好友不存在");
        }

        // 更新好友表
        LambdaUpdateWrapper<Friend> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(Friend::getUserId, userId)
                .eq(Friend::getFriendId, friend.getId())
                .set(Friend::getRemark, remark);
        this.update(updateWrapper);
    }

    @Override
    public void deleteFriend(Long friendId, HttpServletRequest request) {
        // 查询当前用户 UUID
        Long userId = RequestUtils.getUserId(request);

        // 删除好友表
        boolean remove = this.remove(new LambdaQueryWrapper<>(Friend.class)
                .eq(Friend::getUserId, userId)
                .eq(Friend::getFriendId, friendId));

        if (!remove) {
            throw new RuntimeException("删除好友失败");
        }
    }

    //endregion
}




